<?php
/**
 * 生成Db模型
 * 
 * 此方法，自动生成基本的Model程序
 * 
 * @category   Framework
 * @package    __init__
 * @author     Xinze <xinze@live.cn>
 * @copyright  Copyright (c) 2010, 黄新泽
 * @version    1.0
 * @todo       
 */
if (file_exists('../app/configs/config.ini.php'))
{
    require_once '../app/configs/config.ini.php';
}
else
{
    die('请先运行index.php,生成应用程序框架结构！');
}

//判断是否设置db
if (true)
{
    
}

echo '<pre>';

define("CONTROLLER_CLASS_NAME", 'C_'); //控制器class前缀
//define("MODEL_CLASS_NAME", 'M_'); //模型class前缀
define("MODEL_CLASS_NAME", ''); //模型class前缀


define("ACT", 'DEL_');      //是生成还是删除临时文件

define("PRE", false);      //表是否有前缀
define("COMMENT", true);  //sql语句不需要有字段注释

/*
define("COLUMN_NAME_LEN", 4 * 6); //字段长度格式
define("COLUMN_COMMENT_LEN", 24); //字段注释长度格式
*/

define("COLUMN_NAME_LEN", 4 * 6); //字段长度格式
define("COLUMN_COMMENT_LEN", 4 * 6); //字段注释长度格式



define("BR", "\n"); //字段注释长度格式

$Db  = &Zero_Db::get();
$Dbh = $Db->getDbHandle();

define("DATABASE", $Dbh->cfg['main']['database']);

$table_sql = 'SHOW FULL  TABLES   ;';
$table_rows = $Db->getAll($table_sql);

if (!empty($table_rows))
{
    foreach ($table_rows as $key=>$table_row)
    {
        echo "\n";
        echo '生成Model';
        echo "\n";
        
        generate_model($table_row['Tables_in_' . DATABASE]);


        echo "\n";
        echo '生成Controller';
        echo "\n";
        generate_controller($table_row['Tables_in_' . DATABASE]);
    }
}

$table_id = array();

foreach ($table_id as $k=>$v)
{
    $sql = '';
    $Db->exec($sql);
}

function generate_model($table_name)
{
    $table_columns_sql = 'SELECT * FROM information_schema.columns WHERE TABLE_NAME="' . $table_name . '" AND TABLE_SCHEMA="' . DATABASE . '"';

    $Db = &Zero_Db::get();
    global $table_columns_rows;
    $table_columns_rows = $Db->getAll($table_columns_sql);
    
    if (!empty($table_columns_rows))
    {
        global $columns_id_name;
        $columns_id_name = get_id_columns_name($table_name);

        $column_pre = "                    ";
        $column_str = '';
        $dot        = ',';
        $columns_len= count($table_columns_rows) ;


        $insert_str        = '
        $query = \'
                INSERT INTO ' . $table_name . '
                (' . "\n";

        $select_str        = '
        $query = \'
                SELECT
                    SQL_CALC_FOUND_ROWS' . "\n";

        $update_str        = '
        $query = \'
                UPDATE
                    ' . $table_name . '
                SET' . "\n";

        $delete_str        = '
        $query = \'
                    DELETE FROM
                        ' . $table_name . '' . "\n";

        foreach ($table_columns_rows as $key=>$column_row)
        {
            if ($columns_len == $key+1)
            {
                $dot = ' ';
            }

            if (COMMENT)
            {
                $column_row['COLUMN_COMMENT'] = str_replace("\r", "", $column_row['COLUMN_COMMENT']);
                $column_row['COLUMN_COMMENT'] = str_replace("\n", " ", $column_row['COLUMN_COMMENT']);
                $insert_column_comment    = '/* ' . str_pad($column_row['COLUMN_COMMENT'], COLUMN_COMMENT_LEN + strlen($column_row['COLUMN_COMMENT']) - mb_strwidth($column_row['COLUMN_COMMENT'], 'UTF-8')) . '*/';
            }

            $insert_column_name        = '' . str_pad($column_row['COLUMN_NAME'] . '', COLUMN_NAME_LEN-1);
            //$update_column_name        = $insert_column_name . ' = "\' . mres(' . str_pad('$' . $column_row['COLUMN_NAME'], COLUMN_NAME_LEN) . ') . \'"';

            $update_column_name        = $insert_column_name . ' = "\' . mres(' . str_pad('$a[\'' . $column_row['COLUMN_NAME'] . '\']', COLUMN_NAME_LEN) . ') . \'"';

            if (COMMENT)
            {
                $insert_str        .= $column_pre . $insert_column_name . $dot . " " . $insert_column_comment . "\n";
                $select_str        .= $column_pre . $insert_column_name . $dot . " " . $insert_column_comment . "\n";
                $update_str        .= $column_pre . $update_column_name . $dot . " " . $insert_column_comment . "\n";
            }
            else
            {
                $insert_str        .= $column_pre . $insert_column_name . $dot  . "\n";
                $select_str        .= $column_pre . $insert_column_name . $dot  . "\n";
                $update_str        .= $column_pre . $update_column_name . $dot  . "\n";
            }
        }

        $insert_str        .= '                )
                VALUES
                (' . "\n";

        $select_str        .= '                FROM
                    ' . $table_name . '' . "\n";

        $dot        = ',';
        foreach ($table_columns_rows as $key=>$column_row)
        {
            if ($columns_len == $key+1)
            {
                $dot = ' ';
            }

            $insert_column_name        = '"\' . mres(' . str_pad('$a[\'' . $column_row['COLUMN_NAME'] . '\']', COLUMN_NAME_LEN) . ') . \'"';

            $insert_str        .= $column_pre . $insert_column_name . $dot .  "\n";
        }


        $insert_str        .= '                    )\';';
        $select_str        .= '                    \';';
        $update_str        .= '                    \';';
        $delete_str        .= '                    \';';

        //echo $update_str;
        //echo $delete_str;
        //echo $select_str;
        //echo $insert_str;

        $model_class_name = get_model_class_name($table_name);
        $function_suffix_name = get_function_suffix_name($table_name); //函数名称

    $insert_method = '
    /**
     * 插入
     *
     * @param array $a 信息
     * @return bool $rs 是否成功
     * @access private
     */
    private function insert' . $function_suffix_name . '(&$a)
    {' . $insert_str . '

        $rs = $this->sql->exec($query);

        return $rs;
    }' . "\n";

    $table_prefix_row = explode('_', $model_class_name);

    if ('Base' == $table_prefix_row[0])
    {
    $select_method = '
    /**
     * 取得
     *
     * @param int $' . $columns_id_name . ' ' . $columns_id_name . '
     * @return array $rows 信息
     * @access private
     */
    private function select' . $function_suffix_name . '(&$cache_del=null)
    {' . $select_str . '

        $query  .= $this->sql->getWhere();

        if (CHE)
        {
            
            $BaseCache = &Zero_Cache::create(\'base\');

            if ($cache_del)
            {
                $BaseCache->remove($query);
            }

            if ($rows = $BaseCache->get($query))
            {
            }
            else
            {
                $rs = $this->sql->getAll($query);
                $rows = array();

                if($rs)
                {
                    foreach ($rs as $k=>$v)
                    {
                        $rows[$v[\'' . $columns_id_name . '\']] = $v;
                    }
                }

                if (!empty($rows))
                {
                    $BaseCache->save($rows);
                }
            }
        }
        else
        {
            $rs = $this->sql->getAll($query);
            $rows = array();

            if($rs)
            {
                foreach ($rs as $k=>$v)
                {
                    $rows[$v[\'' . $columns_id_name . '\']] = $v;
                }
            }
        }

        return $rows;
    }' . "\n";

    }
    else
    {
    $select_method = '
    /**
     * 取得
     *
     * @param int $' . $columns_id_name . ' ' . $columns_id_name . '
     * @return array $rows 信息
     * @access private
     */
    private function select' . $function_suffix_name . '()
    {' . $select_str . '

        $query  .= $this->sql->getWhere();

        $rows = $this->sql->getAll($query);

        return $rows;
    }' . "\n";

    }

    $update_method = '
    /**
     * 更新
     *
     * @param array $a 更新的数据
     * @return bool $update_flag 是否成功
     * @access private
     */
    private function update' . $function_suffix_name . '(&$a)
    {' . $update_str . '

        $query  .= $this->sql->getWhere();
        $update_flag  = $this->sql->exec($query);

        return $update_flag;
    }' . "\n";

    $delete_method = '
    /**
     * 删除操作
     *
     * @return bool $del_flag 是否成功
     * @access private
     */
    private function delete' . $function_suffix_name . '()
    {' . $delete_str . '

        $query  .= $this->sql->getWhere();
        $del_flag = $this->sql->exec($query);

        return $del_flag;
    }' . "\n";

    //echo $insert_method;
    //echo $select_method;
    //echo $update_method;
    //echo $delete_method;

    $ins_method = '
    /**
     * 插入
     *
     * @param array $a 信息
     * @return bool $rs 是否成功
     * @access public
     */
    public function add' . $function_suffix_name . '(&$a)
    {
        $rs = $this->insert' . $function_suffix_name . '($a);

        return $rs;
    }' . "\n";

    $sel_method = '
    /**
     * 取得
     *
     * @param int $' . $columns_id_name . ' ' . $columns_id_name . '
     * @return array $rows 信息
     * @access public
     */
    public function get' . $function_suffix_name . '()
    {
        $rows = $this->select' . $function_suffix_name . '();

        return $rows;
    }' . "\n";


    $upd_method = '
    /**
     * 更新
     *
     * @param array $a
     * @return bool $update_flag 是否成功
     * @access public
     */
    public function edit' . $function_suffix_name . '(&$a)
    {
        $update_flag  = $this->update' . $function_suffix_name . '($a);

        return $update_flag;
    }' . "\n";

    $del_method = '
    /**
     * 删除操作
     *
     * @param int $' . $columns_id_name . ' ' . $columns_id_name . '
     * @return bool $del_flag 是否成功
     * @access public
     */
    public function remove' . $function_suffix_name . '($' . $columns_id_name . '=null)
    {
        if ($' . $columns_id_name . ')
        {
            $this->sql->setWhere(\'' . $columns_id_name . '\', $' . $columns_id_name . ');
        }

        $del_flag = $this->delete' . $function_suffix_name . '();

        return $del_flag;
    }' . "\n";

    //$ins_method = '';
    //$sel_method = '';
    //$upd_method = '';
    //$del_method = '';
    }

    $year    = date('Y');

    global $package;

/**
 * @name  名字
 * @abstract  申明变量/类/方法
 * @access  指明这个变量、类、函数/方法的存取权限
 * @author  函数作者的名字和邮箱地址
 * @category  组织packages
 * @copyright  指明版权信息
 * @const  指明常量
 * @deprecate  指明不推荐或者是废弃的信息
 * @example  示例
 * @exclude  指明当前的注释将不进行分析，不出现在文挡中
 * @final  指明这是一个最终的类、方法、属性，禁止派生、修改。
 * @global  指明在此函数中引用的全局变量
 * @include  指明包含的文件的信息
 * @link  定义在线连接
 * @module  定义归属的模块信息
 * @modulegroup  定义归属的模块组
 * @package  定义归属的包的信息
 * @param  定义函数或者方法的参数信息
 * @return  定义函数或者方法的返回信息
 * @see  定义需要参考的函数、变量，并加入相应的超级连接。
 * @since  指明该api函数或者方法是从哪个版本开始引入的
 * @static  指明变量、类、函数是静态的。
 * @throws  指明此函数可能抛出的错误异常,极其发生的情况
 * @todo  指明应该改进或没有实现的地方
 * @var  定义说明变量/属性。
 * @version  定义版本信息
 */
    $php_start = '<?php if (!defined(\'ROOT_PATH\')) exit(\'No Permission\');
/**
 * 
 * 
 * 
 * @category   Game
 * @package    ' . $package . '
 * @author     Xinze <xinze@live.cn>
 * @copyright  Copyright (c) ' . $year . ', 黄新泽
 * @version    1.0
 * @todo       
 */
class ' . $model_class_name . ' extends Zero_Model
{
    /**
     * Constructor
     * 
     * @param string $user  User Object
     * @var   string $db_id 指定需要连接的数据库Id
     * @return void
     */
    public function __construct(&$user=null)
    {
        $db_id      = null;
        parent::__construct($db_id, $user);
    }' . "\n";

    $php_end = '}'  . "\n" . '?>';

echo $model_class_name;
echo "\n";

    $file_path = str_replace('_', '/', $model_class_name) . '.php';

    $file_contents = $php_start . $insert_method . $select_method . $update_method . $delete_method . $ins_method . $sel_method . $upd_method . $del_method . $php_end;

    if (file_exists(MOD_PATH . '/' . $file_path))
    {
        if ('DEL' == ACT)
        {
            clean_cache(MOD_PATH . '/temp', true);
            unlink(MOD_PATH . '/' . $file_path . '.tmp');
        }
        else
        {
            make_dir_path(dirname(MOD_PATH . '/temp/' . $file_path));
            make_dir_path(dirname(MOD_PATH . '/' . $file_path));
            file_put_contents(MOD_PATH . '/temp/' . $file_path, $file_contents);
            file_put_contents(MOD_PATH . '/' . $file_path . '.tmp', $file_contents);
        }
    }
    else
    {
        make_dir_path(dirname(MOD_PATH . '/' . $file_path));
        file_put_contents(MOD_PATH . '/' . $file_path, $file_contents);
    }

    echo '生成:' . $file_path . ' 完成';
    echo "\n";
}

function get_model_class_name($table_name)
{
    global $package;
    $table_name_row = explode('_', $table_name);

    if (PRE)
    {
        array_shift($table_name_row);
    }

    $model_class_name = MODEL_CLASS_NAME;
    $class_depth = count($table_name_row);

    foreach ($table_name_row as $key=>$value)
    {
        if (0 == $key)
        {
            if ('' == $value)
            {
                $package = '';
                return $table_name;
            }

            $package = ucfirst($value);

            if (1 == $class_depth)
            {
                $model_class_name .= ucfirst($value); 
            }
            else
            {
                $model_class_name .= ucfirst($value) . '_'; 
            }
        }
        else
        {
            $model_class_name .= ucfirst($value); 
        }
    }

    return $model_class_name;
}

function get_controller_class_name($table_name)
{
    global $package;
    $table_name_row = explode('_', $table_name);

    if (PRE)
    {
        array_shift($table_name_row);
    }

    $controller_class_name = CONTROLLER_CLASS_NAME;
    $class_depth = count($table_name_row);

    foreach ($table_name_row as $key=>$value)
    {
        if (0 == $key)
        {
            if ('' == $value)
            {
                $package = '';
                return $table_name;
            }

            $package = ucfirst($value);

            if (1 == $class_depth)
            {
                $controller_class_name .= ucfirst($value); 
            }
            else
            {
                $controller_class_name .= ucfirst($value) . '_'; 
            }
        }
        else
        {
            $controller_class_name .= ucfirst($value); 
        }
    }

    //foreach ($table_name_row as $key=>$value)
    //{
        //$controller_class_name .= ucfirst($value); 
    //}

    return $controller_class_name;
}

function get_function_suffix_name($table_name)
{
    $table_name_row = explode('_', $table_name);

    if (PRE)
    {
        array_shift($table_name_row);
    }

    $function_suffix_name = '';

    foreach ($table_name_row as $key=>$value)
    {
        if (0 == $key)
        {
            if ('' == $value)
            {
                return $table_name;
            }
        }
        else
        {
            $function_suffix_name .= ucfirst($value); 
        }
    }

    return $function_suffix_name;
}


function get_id_columns_name($table_name)
{
    //真正的数据, 需要从表中取得.
    $Db = &Zero_Db::get();
    $columns = $Db->getRow('SHOW  COLUMNS FROM ' . $table_name . '');

    $columns_name = $columns['Field'];


    return $columns_name;
}


function generate_controller($table_name)
{
    global $table_columns_rows;
    global $columns_id_name;

    if (!empty($table_columns_rows))
    {
        $model_class_name = get_model_class_name($table_name);
        $controller_class_name = get_controller_class_name($table_name);
        $function_suffix_name = get_function_suffix_name($table_name); //函数名称

    $ins_method = '
    /**
     * 插入
     *
     * @param array $a 信息
     * @return bool $rs 是否成功
     * @access public
     */
    public function add()
    {
        $a = $_REQUEST;
        $' . $model_class_name . ' = new ' . $model_class_name . '();

        $rs = $' . $model_class_name . '->add' . $function_suffix_name . '($a);

        return $rs;
    }' . "\n";

    $sel_method = '
    /**
     * 取得
     *
     * @param int $id id
     * @return array $rows 信息
     * @access public
     */
    public function get()
    {
        $' . $model_class_name . ' = new ' . $model_class_name . '();
        $rows = $' . $model_class_name . '->get' . $function_suffix_name . '();

        if (\'e\' == $this->typ)
        {
            print_r($rows);
        }
        else
        {
            $this->data->dataRows[\'body\'] = $rows;
        }

    }' . "\n";


    $upd_method = '
    /**
     * 更新
     *
     * @param array $a
     * @return bool $update_flag 是否成功
     * @access public
     */
    public function edit()
    {
        $a = $_REQUEST;
        $' . $model_class_name . ' = new ' . $model_class_name . '();
        $update_flag  = $' . $model_class_name . '->edit' . $function_suffix_name . '($a);

        return $update_flag;
    }' . "\n";

    $del_method = '
    /**
     * 删除操作
     *
     * @param int $' . $columns_id_name . ' ' . $columns_id_name . '
     * @return bool $del_flag 是否成功
     * @access public
     */
    public function remove()
    {
        $' . $columns_id_name . ' = $_REQUEST[\'' . $columns_id_name . '\'];
        $' . $model_class_name . ' = new ' . $model_class_name . '();

        $' . $model_class_name . '->sql->setWhere(\'' . $columns_id_name . '\', $' . $columns_id_name . ');

        $del_flag = $' . $model_class_name . '->remove' . $function_suffix_name . '();

        return $del_flag;
    }' . "\n";

    //$ins_method = '';
    //$sel_method = '';
    //$upd_method = '';
    //$del_method = '';
    }

    $year    = date('Y');

    global $package;

    $php_start = '<?php if (!defined(\'ROOT_PATH\')) exit(\'No Permission\');
/**
 * 控制器demo，有程序自从生成，作为部分正是项目复制代码使用。
 * 
 * 
 * @category   Game
 * @package    ' . $package . '
 * @author     Xinze <xinze@live.cn>
 * @copyright  Copyright (c) ' . $year . ', 黄新泽
 * @version    1.0
 * @todo       
 */
class ' . $controller_class_name . ' extends Zero_AppController
{
    /**
     * 默认控制的模型
     * 
     * @access public
     * @var Object $' . $model_class_name . '
     */
    public $model = null;

    /**
     * Constructor
     * 
     * @param string $user  User Object
     * @var   string $db_id 指定需要连接的数据库Id
     * @return void
     */
    public function init()
    {
        $this->model = new ' . $model_class_name . '();
    }' . BR;

    $php_end = '}'  . "\n" . '?>';

    echo $controller_class_name;
    echo "\n";

    $file_path = str_replace('_', '/', $controller_class_name) . '.php';

    $file_contents = $php_start  . $ins_method . $sel_method . $upd_method . $del_method . $php_end;

    if (file_exists(CTL_PATH . '/' . $file_path))
    {
        if ('DEL' == ACT)
        {
            clean_cache(CTL_PATH . '/temp', true);
            unlink(CTL_PATH . '/' . $file_path . '.tmp');
        }
        else
        {
            make_dir_path(dirname(CTL_PATH . '/temp/' . $file_path));
            make_dir_path(dirname(CTL_PATH . '/' . $file_path));
            file_put_contents(CTL_PATH . '/temp/' . $file_path, $file_contents);
            file_put_contents(CTL_PATH . '/' . $file_path . '.tmp', $file_contents);
        }
    }
    else
    {
        make_dir_path(dirname(CTL_PATH . '/' . $file_path));
        file_put_contents(CTL_PATH . '/' . $file_path, $file_contents);
    }

    echo '生成:' . $file_path . ' 完成';
    echo "\n";

    $view_path = str_replace('_', '/', $controller_class_name);

    if (!file_exists(TPL_PATH . '/' . $view_path))
    {
        make_dir_path(TPL_PATH . '/' . $view_path);

        if (!file_exists(TPL_PATH . '/' . $view_path . '/' . 'add.php'))
        {
            file_put_contents(TPL_PATH . '/' . $view_path . '/' . 'add.php', '');
            file_put_contents(TPL_PATH . '/' . $view_path . '/' . 'get.php', '');
            file_put_contents(TPL_PATH . '/' . $view_path . '/' . 'remove.php', '');
            file_put_contents(TPL_PATH . '/' . $view_path . '/' . 'edit.php', '');
        }

    }

    echo '生成:' . $file_path . ' 完成';
    echo "\n";
}
?>